#include <iostream>

template<typename T1, typename T2>
int max1(T1 left, T2 right)
{
    std::cout << "max1(" << left << ", " << right << ")" << std::endl;
    return left > right ? left : right;
}

template<typename T1, typename T2, typename... Args>
int max1(T1 left, T2 mid, Args... right)
{
    std::cout << "max1(" << left << ", " << mid << ")" << std::endl;
    return max1(left > mid ? left : mid, right...);
}

template<typename... Args>
int max2(Args... args)
{
    if (sizeof...(Args) == 0) {
        return 0;
    }

    int a[] = {static_cast<int>(args)...};
    int ret = a[0];
    for (int i = 1; i < sizeof(a) / sizeof(*a); i++) {
        std::cout << "a[" << i << "]: " << a[i] << std::endl;
        ret = ret > a[i] ? ret : a[i];
    }
    return ret;
}

int main()
{
    auto result1 = max1(1, 3.5, 2, 4, 5, 0, 8);
    std::cout << "max1 result: " << result1 << std::endl;
    auto result2 = max2(1, 3.5, 2, 4, 5, 0, 8);
    std::cout << "max2 result: " << result2 << std::endl;
    auto result3 = max2();
    std::cout << "max2 result: " << result3 << std::endl;
    return 0;
}
